package main.java.aplicacion.juegos.manejadores;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import main.java.aplicacion.ManejadorSistema;
import main.java.aplicacion.ManejadorSistemaError;
import main.java.aplicacion.categorias.entidades.Categoria;
import main.java.aplicacion.categorias.excepciones.CategoriaError;
import main.java.aplicacion.categorias.manejadores.CategoriaMgr;
import main.java.aplicacion.comentarios.entidades.Comentario;
import main.java.aplicacion.comentarios.excepciones.ComentarioError;
import main.java.aplicacion.juegos.entidades.Aprobado;
import main.java.aplicacion.juegos.entidades.Compra;
import main.java.aplicacion.juegos.entidades.Juego;
import main.java.aplicacion.juegos.entidades.Pendiente;
import main.java.aplicacion.juegos.entidades.Rechazado;
import main.java.aplicacion.juegos.entidades.Version;
import main.java.aplicacion.juegos.excepciones.JuegoError;
import main.java.aplicacion.juegos.interfaces.JuegoMgt;
import main.java.aplicacion.usuarios.entidades.Cliente;
import main.java.aplicacion.usuarios.entidades.Desarrollador;
import main.java.aplicacion.usuarios.excepciones.UsuarioError;
import main.java.aplicacion.usuarios.excepciones.UsuarioError.TipoError;
import main.java.datatypes.comentarios.ComentarioVO;
import main.java.datatypes.juegos.CompraJuegoVO;
import main.java.datatypes.juegos.CompraVO;
import main.java.datatypes.juegos.JuegoVO;
import main.java.datatypes.juegos.VersionVO;

public class JuegoMgr implements JuegoMgt{

	public JuegoMgr() {

	}

	public void agregarJuego(JuegoVO dtJuego) throws JuegoError {
		Juego juego = new Juego(dtJuego);
		ManejadorSistema ms = ManejadorSistema.getInstance();
		if (!existeJuego(dtJuego))
			ms.addJuego(juego);
		else
			throw new JuegoError(JuegoError.TipoError.JUEGO_YA_EXISTE);
	}

	public List<String> altaJuego(String nombre, double tamano, double precio, String descripcion) throws ManejadorSistemaError, JuegoError {

		ManejadorSistema ms = ManejadorSistema.getInstance();
		if (ms.memberJuego(nombre))
			throw new JuegoError(JuegoError.TipoError.JUEGO_YA_EXISTE);
		return ms.listarCategorias();
	}
	
	public List<String> seleccionarCategorias (List<String> ListaCat) throws ManejadorSistemaError
	{
		
		ManejadorSistema m = ManejadorSistema.getInstance();
		return m.listarDesarrolladores(); 
	}

	public boolean existeJuego(JuegoVO dtJuego) {
		Juego juego = new Juego(dtJuego);
		return existeJuego(juego);
	}

	public boolean existeJuego(Juego juego) {
		return ManejadorSistema.getInstance().memberJuego(juego);
	}


	public int seleccionarDesarrollador(String nombre, String nombrej, String dsc, double tam, double p, List<String> cat) throws JuegoError, UsuarioError {
		int i = 0;
		ManejadorSistema m = ManejadorSistema.getInstance();

			m.memberJuego(nombrej);
			Juego j = new Juego(nombrej, dsc, tam, p);
			Desarrollador d = (Desarrollador) m.findUsuarioPorNick(nombre);
			if (d == null)
			{
				throw new UsuarioError(TipoError.USUARIO_NO_EXISTE);
			}
			else {
				d.getJuegosPublicados().add(j);
				j.setDesarrollador(d);
				CategoriaMgr mc = new CategoriaMgr();
				List<Categoria>  categorias = mc.obtenerCategorias(cat);
				j.setCategorias(categorias);
				if(!categorias.isEmpty()){
					for(Categoria catActual: categorias){
						if (catActual.getJuegos() == null){
							List<Juego> lj = new ArrayList <Juego>();
							catActual.setJuegos(lj);
						}
						catActual.getJuegos().add(j);
					}
				}
				i = m.addJuego(j);
				j.setNumero(i);
			}
			return i;
	
		
		//return i;
	}

	public List<String> consultarJuego() throws ManejadorSistemaError {
		ManejadorSistema m = ManejadorSistema.getInstance();
		return m.listarCategorias();
	}

	public List<String> seleccionarCategoria(String nom) throws CategoriaError, ManejadorSistemaError {
		ManejadorSistema m = ManejadorSistema.getInstance();
		return m.listarJuegosCategoria(nom);
	}

	public JuegoVO seleccionarJuego(String nom) throws JuegoError {
		
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego j = ms.findJuego(nom);
		if (j != null)
			return j.getJuegoVO();
		else
			throw new JuegoError(JuegoError.TipoError.JUEGO_NO_EXISTE);
	}

	public Juego find(String nom) {
		ManejadorSistema ms = ManejadorSistema.getInstance();
		if (ms.IsEmptyJuegos()) {
			return null;
		} else {
			 return ms.findJuego(nom);
		}
	}

	public List<CompraJuegoVO> comprarJuego() {
		
		ManejadorSistema m = ManejadorSistema.getInstance();
		if(m.IsEmptyJuegos())
			return null;
		else {
			List<CompraJuegoVO> list = new LinkedList<CompraJuegoVO>();
			list = m.listarDataCompra();
			return list;
		}
	}

	public CompraVO seleccionarJuego(String juego, String nick, Date f) {
		ManejadorSistema m = ManejadorSistema.getInstance();
		return  new CompraVO(juego, nick, m.findJuego(juego).getPrecio(), f);
	}

	public void confirmarCompra(Date f, String cliente, String juego) {

		ManejadorSistema m = ManejadorSistema.getInstance();
		Cliente cli = (Cliente) m.findUsuarioPorNick(cliente);
		Compra c = new Compra(f, cli);
		m.findJuego(juego).addCompraJuego(c);
		((Cliente) m.findUsuarioPorNick(cliente)).registrarCompra(m.findJuego(juego));
	}
	
	public List<String> listarJuegos() throws ManejadorSistemaError{
		ManejadorSistema ms = ManejadorSistema.getInstance();
		return ms.listarJuegos();
	}

	public List<ComentarioVO> nuevoComentario(String juego) throws JuegoError{
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego j = ms.findJuego(juego);
		if(j != null){
			return (j.getJuegoVO().getComentarios());
		}
		else
			throw new JuegoError(JuegoError.TipoError.JUEGO_NO_EXISTE);
	}
	
	public int ingresarDatosComentario(ComentarioVO com) throws ComentarioError{
		
		com.setNumero(ManejadorSistema.getInstance().getNumeroComentarios()+1);
		ManejadorSistema.getInstance().setNumeroComentarios(); 
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Comentario comentario = new Comentario(com);
		comentario.setUsuario(ms.findUsuarioPorNick(com.getCliente()));
		comentario.setJuego(ms.findJuego(com.getJuego()));

		if(com.getRespondeA() > 0){
			List<Comentario> comJuego = ms.findJuego(com.getJuego()).getComentarios();
			if(comJuego != null){
				Comentario c = null;
				for (Comentario comentarioActual : comJuego) {
					if (comentarioActual.getNumero() == com.getRespondeA()) {
						c = comentarioActual;
					}
				}
				if(c != null){
					comentario.setRespondeA(c);
					c.agregarRespuesta(comentario);
				}
				else
					throw new ComentarioError(ComentarioError.TipoError.COMENTARIO_NO_EXISTE); 
			}
			else
				throw new ComentarioError(ComentarioError.TipoError.COMENTARIO_NO_EXISTE); 
		}
		(ms.findJuego(com.getJuego())).registrarComentario(comentario);
		return com.getNumero();
	}
	
	public JuegoVO obtenerJuego(String juego){
		
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego j = ms.findJuego(juego);
		if(j != null) 
			return j.getJuegoVO();
		else 
			return null;
	}
	
	
	public void crearJuego(String nombre, String cat, String dev, String tam, String precio){
		try {
			seleccionarDesarrollador(dev, nombre, "", Double.parseDouble(tam), Double.parseDouble(precio), Arrays.asList(new String[]{cat}));
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JuegoError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UsuarioError e) {
			
			e.printStackTrace();
		}
	}
	

	public void agregarCategoria(String nombreJuego, String nombreCat){
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego jue = ms.findJuego(nombreJuego);
		Categoria cat = ms.findCategoria(nombreCat);
		jue.getCategorias().add(cat);
		cat.add(jue);
	}
	public void agregarDescr(String nombre, String descr){
		ManejadorSistema ms = ManejadorSistema.getInstance();
		ms.findJuego(nombre).setDescripcion(descr);
	}
	
	public void agregarCompra(String cliente, String juego, String fecha, String hora){
		String[] dma = fecha.split("/");
		Date date = java.sql.Timestamp.valueOf(dma[2] + "-" + dma[1]+ "-" + dma[0] + " " + hora + ":00");
		confirmarCompra(date, cliente, juego);
	}
	
	public void agregarCompra(String cliente, String juego, Date fecha){
		confirmarCompra(fecha, cliente, juego);
	}
	
	
	public int agregarComentario(int respondeA, String cliente, String juego, String fecha, String hora, String texto){
		String[] dma = fecha.split("/");
		Date date = java.sql.Timestamp.valueOf(dma[2] + "-" + dma[1]+ "-" + dma[0] + " " + hora + ":00");
		ComentarioVO com = new ComentarioVO(respondeA, texto, date, cliente, juego);
		com.setRespondeA(respondeA);
		//hay que setearle la a quien responde y si responde a alguien
		int i = 0;
		try {
			i = ingresarDatosComentario(com);
		} catch (ComentarioError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return i;
	}
	
	public int agregarComentario(int respondeA, String cliente, String juego, Date fecha , String texto){
		ComentarioVO com = new ComentarioVO(respondeA, texto, fecha, cliente, juego);
		com.setRespondeA(respondeA);
		//hay que setearle la a quien responde y si responde a alguien
		int i = 0;
		try {
			i = ingresarDatosComentario(com);
		} catch (ComentarioError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return i;
	}
	
	public boolean ClientePuedeComprar(String j, String nick){
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego juego = ms.findJuego(j); 
		List<Compra> lc = juego.getCompras();
		if(lc!=null){
		for(Compra c: lc){
			if(c.getCliente().getNick().equals(nick)){
				return false;
			}
		}
		}
		return true;
	}
	
	public List<VersionVO> listarJuegosPendientes(){
		ManejadorSistema ms = ManejadorSistema.getInstance();
		List<VersionVO> lv = ms.listarJuegosPendientes();
		return lv;
	}
	
	public void aceptarVersion(VersionVO version){
		
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego j = ms.findJuego(version.getNombreJuego());
		if(j!=null){
			List<Version> lv = j.getVersiones();
			for(Version v: lv){
				if((v.getNumero() == version.getNumero())&&(Pendiente.class.isInstance(v.getEstado()))){
					v.setEstado(new Aprobado());
					j.setUltAprobada(v);
					j.getVersionesAprobadas().add(j.getVersionVO(v));
				}
			}
		}
	}
	
	public void rechazarVersion(VersionVO version, String motivo){
		
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego j = ms.findJuego(version.getNombreJuego());
		if(j!=null){
			List<Version> lv = j.getVersiones();
			for(Version v: lv){
				if((v.getNumero() == version.getNumero())&&(Pendiente.class.isInstance(v.getEstado()))){
					v.setEstado(new Rechazado(motivo));
				}
			}
		}
	}
	
	public boolean existeVersionPendienteAprobada(String nombreJuego, String numero){
		
		ManejadorSistema ms = ManejadorSistema.getInstance();
		Juego juego = ms.findJuego(nombreJuego);
		if(juego != null){
			for(Version v: juego.getVersiones()){
				if((v.getNumero().equals(numero))&&((Pendiente.class.isInstance(v.getEstado()))||(Aprobado.class.isInstance(v.getEstado())))){
					return true;
				}
			}
		}
		return false;
	}
	
	public List<String> seleccionarCategoriaWeb(String nom) throws CategoriaError, ManejadorSistemaError {
		ManejadorSistema m = ManejadorSistema.getInstance();
		return m.listarJuegosAprobCategoria(nom);
	}
	
	public JuegoVO seleccionarJuegoWeb(String nom) throws JuegoError {
		
		JuegoVO jvoW = this.seleccionarJuego(nom);
		ManejadorSistema m = ManejadorSistema.getInstance();
		jvoW.setNumeroVersion(m.findJuego(nom).getUltAprobada().getNumero());
		return jvoW;
	}
	
	public String getLinkJuego(String nom)
	{
		ManejadorSistema m = ManejadorSistema.getInstance();
		return m.findJuego(nom).getUltAprobada().getDirVersion();
	}
	
	public void altaVersionJuego(String nombreJuego, String numeroVersion,  double tamanio, String dirVersion){
		Juego juego = ManejadorSistema.getInstance().findJuego(nombreJuego);
		if(juego != null){
			 Version v = new Version(numeroVersion, tamanio, dirVersion);
			 juego.getVersiones().add(v);
		}
	}
	
	public List<JuegoVO> listarJuegosVO() {
		ManejadorSistema ms = ManejadorSistema.getInstance();
		return ms.listarJuegosVO();
	}
	
}
